package cn.com.w.redis.use.service;

import cn.com.w.redis.use.common.annotation.RankTypeFactory;
import cn.com.w.redis.use.common.enums.RankTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 排行榜策略上下文
 */
@Component
@Slf4j
public class RankStrategyContext implements ApplicationContextAware {

    /**
     * 所有 RankStrategy 实现类
     */
    private static Map<RankTypeEnum, RankStrategy> rankStrategyMap;

    /**
     * 自动加载所有实现类
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 获取 RankStrategy 接口的所有实现类
        Map<String, RankStrategy> beansOfType = applicationContext.getBeansOfType(RankStrategy.class);
        rankStrategyMap = new HashMap<>();

        // 将实现类放入map中，key为实现类对应的枚举，value为实现类
        for (RankStrategy item : beansOfType.values()) {
            RankTypeFactory annotation = item.getClass().getAnnotation(RankTypeFactory.class);
            if (null != annotation) {
                rankStrategyMap.put(annotation.value(), item);
            }
        }

        log.info("RankStrategy 实现类数量={}", rankStrategyMap.keySet().size());
    }

    /**
     * 获取实现类
     *
     * @param typeCode
     * @return RankStrategy
     */
    public static RankStrategy getStrategy(Integer typeCode) throws RuntimeException {
        return rankStrategyMap.get(getRankType(typeCode));
    }

    /**
     * 根据typeCode获取枚举RankTypeEnum
     *
     * @param typeCode
     * @return
     */
    public static RankTypeEnum getRankType(Integer typeCode) {
        for (RankTypeEnum item : RankTypeEnum.values()) {
            if (item.getTypeCode().equals(typeCode)) {
                return item;
            }
        }
        throw new RuntimeException("服务不存在");
    }

}
